<template>
  <!-- 充电站管理 - 营收统计 -->
  <div>
    <!-- 数据总览 -->
    <el-row :gutter="20">
      <!-- 循环项 -->
      <el-col :span="4" v-for="(item, index) in overviewData" :key="index">
        <el-card>
          <!-- 标题 -->
          <div class="title">
            <!-- 图标 -->
            <div class="round">
              <el-icon>
                <Document />
              </el-icon>
            </div>
            <h4>{{ item.title }}</h4>
          </div>

          <!-- 显示数字 -->
          <div class="total mt">
            <h1>{{ formatNumber(item.amount) }}</h1>
            <div :class="['persent', item.trend]">
              {{ item.trend === "increase" ? "+" : "-" }}{{ item.percentage }}%
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 销售额图表 -->
    <el-card class="mt">
      <div ref="chartRef" style="width: 100%; height: 300px"></div>
    </el-card>

    <!-- 营收统计数据列表 -->
    <el-card class="mt">
      <!-- 搜索框 -->
      <el-input v-model="name" style="max-width: 400px" placeholder="请输入站点名称">
        <template #append>
          <el-button :icon="Search" @click="loadData"></el-button>
        </template>
      </el-input>

      <!-- 表格数据 -->
      <el-table :data="tableData" v-loading="loading">
        <el-table-column type="index" label="序号" width="80"></el-table-column>
        <el-table-column label="充电站名称" prop="name"></el-table-column>
        <el-table-column label="充电站ID" prop="id"></el-table-column>
        <el-table-column label="充电站所属城市" prop="city"></el-table-column>
        <el-table-column label="充电桩总数量(个)" prop="count"></el-table-column>
        <el-table-column label="单日总收入(元)" prop="day" sortable>
          <!-- 百分比处理 -->
          <template #default="scope">
            <!-- 总收入 -->
            <span>{{ scope.row.day }}</span>
            <!-- 百分比数值及状态 -->
            <el-tag :type="scope.row.percent > 0 ? 'danger' : 'success'" class="ml">
              {{
                scope.row.percent > 0
                  ? "+" + scope.row.percent + "%"
                  : scope.row.percent + "%"
              }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="月度总收入(元)" prop="month">
          <!-- 百分比处理 -->
          <template #default="scope">
            <!-- 总收入 -->
            <span>{{ scope.row.month }}</span>
            <!-- 百分比数值及状态 -->
            <el-tag :type="scope.row.mpercent > 0 ? 'danger' : 'success'" class="ml">
              {{
                scope.row.mpercent > 0
                  ? "+" + scope.row.mpercent + "%"
                  : scope.row.mpercent + "%"
              }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="电费营收(元)" prop="electricity"></el-table-column>
        <el-table-column label="停车费营收(元)" prop="parkingFee"></el-table-column>
        <el-table-column label="服务费营收(元)" prop="serviceFee"></el-table-column>
        <el-table-column label="会员储值金(元)" prop="member"></el-table-column>
      </el-table>

      <!-- 分页 -->
      <el-pagination
        class="mt mb fr"
        v-model:current-page="pageInfo.page"
        v-model:page-size="pageInfo.pageSize"
        :page-sizes="[10, 20, 30, 40]"
        bakeground
        layout="total, sizes, prev, pager, next, jumper"
        :total="totals"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>
  </div>
</template>

<script setup lang="ts">
// 引入 tool.ts 工具类里的 千分位格式化 函数
import { formatNumber } from "@/utils/tool";
import { onMounted, ref, reactive } from "vue";
import { Search } from "@element-plus/icons-vue";

/**
 * 功能作用: 调用API获取数据总览的循环项数据
 *
 * 功能描述:
 * 1:引入 overviewApi 函数,用于获取数据总览的循环项数据
 * 2:定义 OverviewItem 接口数据类型,用于描述数据总览的循环项数据
 * 3:定义 overviewData 响应式变量,用于存储数据总览的循环项数据
 * 4:定义 loadOverviewData 函数,用于调用 overviewApi 函数并获取数据总览的循环项数据
 * 4.1:在 loadOverviewData 函数中,使用 try-catch 语句处理异常
 * 4.2:在 try 块中,调用 overviewApi 函数获取数据
 * 4.3:如果返回的 res.code 为 200,则将 res.data 赋值给 overviewData
 * 4.4:在 catch 块中,打印错误信息
 * 5:在 onMounted 钩子函数中调用 loadOverviewData 函数,确保组件加载时获取数据
 */
import { overviewApi } from "@/api/chargingstation";
interface OverviewItem {
  title: string;
  amount: number;
  trend: "increase" | "decrease";
  percentage: number;
}
// 定义响应式变量 overviewData,用于存储数据总览的循环项数据
const overviewData = ref<OverviewItem[]>([]);
const loadOverviewData = async () => {
  try {
    const res = await overviewApi();
    if (res.code === 200) {
      overviewData.value = res.data;
    }
  } catch (error) {
    console.error("数据总览的循环项数据-报错:", error);
  }
};
onMounted(() => {
  loadOverviewData();
});

/**
 * 功能作用: 销售额图表数据的配置与加载
 *
 * 功能描述:
 * 1:引入 salesApi 函数,用于获取销售额图表数据
 * 2:引入 useChart 函数,用于处理 ECharts 图表数据,他是自定义的组合式 API,传入 chartRef(模板锚点) 和 setChartData(配置项) 作为参数
 * 3:定义 chartRef 变量,用于获取图表的引用,让你能够：直接访问图表组件实例,调用图表的内置方法（如更新、销毁等）,操作图表的 DOM 元素
 * 4:创建 setChartData 函数,用于处理销售额图表数据
 * 4.1:在 setChartData 函数中,定义 ECharts 的图表配置项,包括标题、提示框、图例、坐标轴、系列等
 * 4.2:调用 salesApi 函数获取数据
 * 4.3:判断接口返回的状态码是否为 200,如果是,则将接口返回的数据赋值给图表配置项
 * 4.4:返回图表配置项
 * 5:调用 useChart 函数,传入 chartRef 和 setChartData 作为参数,用于处理 ECharts 图表数据
 * 注意:
 * 1. 确保 ECharts 组件已经正确安装并引入
 * 2. 确保接口返回的数据格式与图表配置项中的数据格式一致
 * 3. 如果需要动态更新图表数据,可以在 setChartData 函数中添加逻辑来处理数据变化
 * 4. 如果需要处理其他类型的图表,可以根据 ECharts 的文档进行相应的配置
 *
 */
import { salesApi } from "@/api/chargingstation";
import { useChart } from "@/hokes/useChart";
const chartRef = ref<HTMLElement | null>(null);
const setChartData = async () => {
  // 定义图表配置
  const chartOptions = reactive({
    tooltip: {
      trigger: "axis",
    },
    legend: {
      data: [],
    },
    xAxis: {
      type: "category",
      data: ["一月", "二月", "三月", "四月", "五月", "六月", "七月"],
    },
    yAxis: [
      {
        type: "value",
        name: "销售",
        position: "left",
      },
      {
        type: "value",
        name: "访问量",
        position: "right",
      },
    ],
    series: [
      {
        name: "",
        type: "bar",
        data: [],
        yAxisIndex: 0,
        itemStyle: {
          color: "#409eff",
        },
      },
      {
        name: "",
        type: "line",
        data: [],
        yAxisIndex: 1,
        itemStyle: {
          color: "#409eff",
        },
        smooth: true,
      },
    ],
  });

  const res = await salesApi();
  if (res.code === 200) {
    chartOptions.legend.data = res.data.list.map((item: any) => item.name);

    for (let i = 0; i < res.data.list.length; i++) {
      chartOptions.series[i].name = res.data.list[i].name;
      chartOptions.series[i].data = res.data.list[i].data;
    }
  }

  return chartOptions;
};
useChart(chartRef, setChartData);

/**
 * 功能作用; 获取营收统计数据列表,并实现分页功能
 *
 * 功能描述:
 * 1:先搭建HTML模板部分,用了element-plus的组件,包括el-row,el-col,el-card,el-table等
 * 2:声明 tableData 响应式变量,用于存储营收统计数据列表,也用于 el-table 的 data 属性
 * 3:声明 loading 响应式变量,用于控制 el-table 的加载状态
 * 4:声明 name 响应式变量,用于存储站点名称的搜索条件
 * 5:引入 statisticsApi 函数,用于获取营收统计数据列表
 * 6:定义 loadData 函数,用于调用 statisticsApi 函数并获取营收统计数据列表
 * 6.1:在 loadData 函数中,使用 try-catch 语句处理异常
 * 6.2:在 try 块中,设置 loading 为 true,表示开始加载数据
 * 6.3:调用 statisticsApi 函数,传入分页参数 pageInfo 和搜索条件 name,把获取到的数据赋值给 res
 * 6.4:如果返回的 res.code 为 200,则将 res.data.list 赋值给 tableData
 * 6.5:设置 loading 为 false,表示加载完成
 * 6.6:处理单日总收入逻辑,根据电费营收(元),停车费营收(元),服务费营收(元) 这三列数据计算单日总收入
 * 6.7:为分页组件设置总条数,调用 setTotals 方法,这个方法是从自定义函数 usePagination 中获取的
 * 6.8:在 catch 块中,打印错误信息
 * 7:引入 usePagination 自定义函数,用于处理分页逻辑
 * 7.1:从 usePagination 中解构赋值,获取 totals(总条数), pageInfo(分页参数), handleSizeChange(每页条数变化事件), handleCurrentChange(页码变化事件), setTotals(设置总条数方法)
 * 7.2:把 loadData 函数传入 usePagination 作为参数,这样当分页参数变化时,会自动调用 loadData 函数重新加载数据
 * 8:在 onMounted 钩子函数中调用 loadData 函数,确保组件加载时获取数据
 *
 * 注意:
 * 这部分代码主要是处理营收统计数据列表的获取和展示,使用了 element-plus 的表格组件 el-table 来展示数据
 * 需要确保 statisticsApi 函数已经正确实现并返回符合预期的数据格式
 * 需要确保 tableData 和 loading 响应式变量已经正确声明并绑定到模板中
 * 需要确保在组件加载时调用 loadData 函数来获取数据
 */

const tableData = ref([]);
const loading = ref(false);
const name = ref<string>("");
import { statisticsApi } from "@/api/chargingstation";
const loadData = async () => {
  try {
    loading.value = true;
    const res = await statisticsApi({
      ...pageInfo,
      name: name.value,
    });
    if (res.code === 200) {
      tableData.value = res.data.list;
      loading.value = false;
      // 处理单日总收入逻辑,根据电费营收(元),停车费营收(元),服务费营收(元) 这三列数据计算单日总收入
      tableData.value.forEach((item: any) => {
        item.day = (item.electricity + item.parkingFee + item.serviceFee).toFixed(2);
      });
      // 为分页组件设置总条数
      setTotals(res.data.total);
    }
  } catch (error) {
    console.error("数据总览的循环项数据-报错:", error);
  }
};
import { usePagination } from "@/hokes/useCommonly.ts";

const {
  totals,
  pageInfo,
  handleSizeChange,
  handleCurrentChange,
  setTotals,
} = usePagination(loadData);

onMounted(() => {
  loadData();
});
</script>

<style scoped lang="less">
.title {
  display: flex;
  align-items: center;
  .round {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background-color: rgba(235, 236, 245);
    text-align: center;
    line-height: 30px;
    margin-right: 20px;
  }

  h4 {
    color: #666;
  }
}

.total {
  display: flex;
  align-items: center;
  h1 {
    font-size: 30px;
    margin-right: 20px;
  }

  .persent {
    display: inline-block;
    padding: 3px 5px;
    height: 20px;
    font-size: 12px;
    background-color: rgb(235, 247, 239);
    border-radius: 2px;
    line-height: 20px;
    /* 趋势样式类 */
    &.increase {
      color: #f56c6c; /* 红色表示上涨 */
      font-weight: bold;
    }

    &.decrease {
      color: #67c23a; /* 绿色表示下跌 */
      font-weight: bold;
    }
  }
}
</style>
